import { InjectionKey } from 'vue'
import { ActionTree, createStore, GetterTree, MutationTree, Store, StoreOptions, useStore } from 'vuex'
import { EDeviceTypeName } from '../types'
import { Device, DeviceHms, DeviceOsd, DeviceStatus, DockOsd, GatewayOsd, OSDVisible } from '../types/device'
import { getLayers } from '@/api/layer'
import { LayerType } from '@/types/mapLayer'
import { TemplateTypes, WayLineFile, WaylineFile } from '@/types/wayline'
import { DevicesCmdExecuteInfo } from '@/types/device-cmd'
import { FlightAreaStatus } from '../api/flight-area'
import { title } from 'process'

const initStateFunc = () => ({
  Layers: [
    {
      name: 'default',
      id: '',
      is_distributed: true,
      elements: [],
      is_check: false,
      is_select: false,
      type: 1
    },
    {
      name: 'share',
      id: '',
      is_distributed: true,
      elements: [],
      is_check: false,
      is_select: false,
      type: 2
    }
  ],
  layerBaseInfo: {} as {
    [key: string]: string
  },
  drawVisible: false,
  livestreamOthersVisible: false,
  livestreamAgoraVisible: false,
  coverMap: {} as {
    [key: string]: any[]
  },
  wsEvent: {
    mapElementCreat: {},
    mapElementUpdate: {},
    mapElementDelete: {}
  },
  deviceStatusEvent: {
    deviceOnline: {} as DeviceStatus,
    deviceOffline: {}
  },
  markerInfo: {
    coverMap: {} as {
      [sn: string]: any
    },
    pathMap: {} as {
      [sn: string]: any[]
    }
  },
  deviceState: {
    // remote controller, dock
    gatewayInfo: {} as {
      [sn: string]: GatewayOsd
    },
    // drone
    deviceInfo: {} as {
      [sn: string]: DeviceOsd
    },
    dockInfo: {} as {
      [sn: string]: DockOsd
    },
    currentSn: '',
    currentType: -1
  },
  osdVisible: {
    // osd 显示设备相关信息
    sn: '',
    callsign: '',
    model: '',
    visible: false,
    gateway_sn: '',
    is_dock: false,
    payloads: null
  } as OSDVisible,
  // waylineInfo: {} as WaylineFile,
  waylineInfo: {} as WayLineFile<TemplateTypes[]>,
  dockInfo: {} as Device,
  hmsInfo: {} as {
    [sn: string]: DeviceHms[]
  },
  // 机场指令执行状态信息
  devicesCmdExecuteInfo: {} as DevicesCmdExecuteInfo,
  mqttState: null as any, // mqtt 实例
  clientId: '', // mqtt 连接 唯一客户端id
  mediaInfo: {
    total_photo_num: 0,
    total_video_num: 0,
    total_photo_size: '0',
    total_video_size: '0'
  },
  // 控制航线详情页面是否显示
  isShowControlWayline: false,
  // 航线详情的数据，包括(航线长度,预计执行时间,航线数量,照片),(面积,航线总长度，预计总时间,预计总照片)
  singleWaylineData: [
    {
      title: '航线长度',
      value: ''
    },
    {
      title: '预计执行时间',
      value: ''
    },
    {
      title: '航点',
      value: 0
    },
    {
      title: '照片',
      value: 0
    }
  ],
  totalWaylineData: [
    {
      title: '面积',
      value: ''
    },
    {
      title: '航线总长度',
      value: ''
    },
    {
      title: '预计总时间',
      value: 0
    },
    {
      title: '预计总照片数',
      value: 0
    }
  ],
  inclineWaylineData: [
    {
      title: '面积',
      value: ''
    },
    {
      title: '航线总长度',
      value: ''
    },
    {
      title: '预计总时间',
      value: 0
    },
    {
      title: '预计总照片数',
      value: 0
    }
  ],
  inclinePointInfo: {},
  inclineInfo: {
    // 选中的航线，默认是第一条
    index: 1,
    // 一共有多少条航线数据
    total: 0,
    // 每一条的航线数据
    data: [
      {
        title: '航线长度',
        value: ''
      },
      {
        title: '预计时间',
        value: ''
      },
      {
        title: '照片数',
        value: 0
      },
    ],
  },
  // 展示什么类型的航线
  showWaylineType: 1, // 1:纯航线任务 2:面状正射任务,3:面状倾斜摄影
  // 媒体库类型查询
  mediaType: 0, // 1:全部 2:照片 3:视频
})

export type RootStateType = ReturnType<typeof initStateFunc>

const getters: GetterTree<RootStateType, RootStateType> = {}
const mutations: MutationTree<RootStateType> = {
  SET_LAYER_INFO(state, info) {
    state.Layers = info
  },
  SET_DEVICE_INFO(state, info) {
    state.deviceState.deviceInfo[info.sn] = info.host
    state.deviceState.currentSn = info.sn
    state.deviceState.currentType = EDeviceTypeName.Aircraft
  },
  SET_GATEWAY_INFO(state, info) {
    state.deviceState.gatewayInfo[info.sn] = info.host
    state.deviceState.currentSn = info.sn
    state.deviceState.currentType = EDeviceTypeName.Gateway
  },
  SET_DOCK_INFO(state, info) {
    if (Object.keys(info.host).length === 0) {
      return
    }
    if (!state.deviceState.dockInfo[info.sn]) {
      state.deviceState.dockInfo[info.sn] = {} as DockOsd
    }
    state.deviceState.currentSn = info.sn
    state.deviceState.currentType = EDeviceTypeName.Dock
    const dock = state.deviceState.dockInfo[info.sn]
    if (info.host.mode_code !== undefined) {
      dock.basic_osd = info.host
      return
    }
    if (info.host.wireless_link) {
      dock.link_osd = info.host
      return
    }
    if (info.host.job_number !== undefined) {
      dock.work_osd = info.host
    }
  },
  SET_DRAW_VISIBLE_INFO(state, bool) {
    state.drawVisible = bool
  },
  SET_LIVESTREAM_OTHERS_VISIBLE(state, bool) {
    state.livestreamOthersVisible = bool
  },
  SET_LIVESTREAM_AGORA_VISIBLE(state, bool) {
    state.livestreamAgoraVisible = bool
  },
  SET_MAP_ELEMENT_CREATE(state, info) {
    state.wsEvent.mapElementCreat = info
  },
  SET_MAP_ELEMENT_UPDATE(state, info) {
    state.wsEvent.mapElementUpdate = info
  },
  SET_MAP_ELEMENT_DELETE(state, info) {
    state.wsEvent.mapElementDelete = info
  },
  SET_DEVICE_ONLINE(state, info) {
    state.deviceStatusEvent.deviceOnline = info
  },
  SET_DEVICE_OFFLINE(state, info) {
    state.deviceStatusEvent.deviceOffline = info
    delete state.deviceState.gatewayInfo[info.sn]
    delete state.deviceState.deviceInfo[info.sn]
    delete state.deviceState.dockInfo[info.sn]
    delete state.hmsInfo[info.sn]
    // delete state.markerInfo.coverMap[info.sn]
    // delete state.markerInfo.pathMap[info.sn]
  },
  SET_OSD_VISIBLE_INFO(state, info) {
    state.osdVisible = info
  },
  SET_SELECT_WAYLINE_INFO(state, info) {
    state.waylineInfo = info
  },
  SET_SELECT_DOCK_INFO(state, info) {
    state.dockInfo = info
  },
  SET_DEVICE_HMS_INFO(state, info) {
    const hmsList: Array<DeviceHms> = state.hmsInfo[info.sn]
    state.hmsInfo[info.sn] = info.host.concat(hmsList ?? [])
  },
  SET_DEVICES_CMD_EXECUTE_INFO(state, info) {
    // 保存设备指令ws消息推送
    if (!info.sn) {
      return
    }
    if (state.devicesCmdExecuteInfo[info.sn]) {
      const index = state.devicesCmdExecuteInfo[info.sn].findIndex((cmdExecuteInfo) => cmdExecuteInfo.biz_code === info.biz_code)
      if (index >= 0) {
        // 丢弃前面的消息
        if (state.devicesCmdExecuteInfo[info.sn][index].timestamp > info.timestamp) {
          return
        }
        state.devicesCmdExecuteInfo[info.sn][index] = info
      } else {
        state.devicesCmdExecuteInfo[info.sn].push(info)
      }
    } else {
      state.devicesCmdExecuteInfo[info.sn] = [info]
    }
  },
  SET_MQTT_STATE(state, mqttState) {
    state.mqttState = mqttState
  },
  SET_CLIENT_ID(state, clientId) {
    state.clientId = clientId
  },
  getMediaInfo(state) {
    console.log('state.mediaInfo', state.mediaInfo)
    return state.mediaInfo
  },
  SET_TOTAL_WAYLINE_DATA_INFO(state, info) {
    state.showWaylineType = 2
    console.log('SET_TOTAL_WAYLINE_DATA_INFO', info)
    const updatedData = [
      { title: '面积', value: `${info.area}m²` },
      { title: '航线总长度', value: `${info.distance}米` },
      { title: '预计总时间', value: info.duration },
      { title: '预计总照片数', value: info.photo_num },
    ]
    state.totalWaylineData = updatedData
  },
  SET_SINGLE_WAYLINE_DATA_INFO(state, info) {
    console.log('SET_SINGLE_WAYLINE_DATA_INFO', info)
    const updatedData = [
      { title: '航线长度', value: `${info.distance}米` },
      { title: '预计执行时间', value: info.duration },
      { title: '航点', value: info.pointNun },
      { title: '照片', value: info.photo_num },
    ]
    state.showWaylineType = 1
    state.singleWaylineData = updatedData
  },
  SET_INCLINE_WAYLINE_DATA_INFO(state, info) {
    state.showWaylineType = 3
    console.log('SET_ORIGIN_WAYLINE_DATA_INFO', info)
    const updatedData = [
      { title: '面积', value: `${info.area}m²` },
      { title: '航线总长度', value: `${info.distance}米` },
      { title: '预计总时间', value: info.duration },
      { title: '预计总照片数', value: info.photo_num },
    ]
    state.inclineWaylineData = updatedData
  },
  SET_INCLINE_INFO(state, info) {
    const { index, total, data } = info
    console.log('SET_ORIGIN_INFO', info)
    // state.originInfo.index = index
    // state.originInfo.total = total
    const updatedData = [
      { title: '航线长度', value: `${data.distance}米` },
      { title: '预计时间', value: data.duration },
      { title: '照片数', value: data.photo_num },
    ]
    state.inclineInfo = {
      index,
      total,
      data: updatedData,
    }
  },
  SET_INCLINE_POINT_INFO(state, info) {
    state.inclinePointInfo = info
  },
  // 修改当前航线信息框是否显示
  SET_IS_SHOW_CONTROL_WAYLINE(state, bool) {
    state.isShowControlWayline = bool
  },
  SET_MEDIA_TYPE(state, type) {
    state.mediaType = type
  }
}

const actions: ActionTree<RootStateType, RootStateType> = {
  async getAllElement({ commit }) {
    const result = await getLayers({
      groupId: '',
      isDistributed: true
    })
    commit('SET_LAYER_INFO', result.data?.list)
    console.log(result)
  },
  updateElement({ state }, content: { type: 'is_check' | 'is_select'; id: string; bool: boolean }) {
    const key = content.id.replaceAll('resource__', '')
    const type = content.type
    const layers = state.Layers
    const layer = layers.find((item) => item.id === key)
    if (layer) {
      layer[type] = content.bool
    }
  },
  setLayerInfo({ state }, layers) {
    // const layers = state.Layers
    const obj: {
      [key: string]: string
    } = {}
    layers.forEach((layer) => {
      if (layer.type === LayerType.Default) {
        obj.default = layer.id
      } else {
        if (layer.type === LayerType.Share) {
          obj.share = layer.id
        }
      }
    })
    state.layerBaseInfo = obj
    console.log('state.layerBaseInfo', state.layerBaseInfo)
  },
  getLayerInfo({ state }, id: string) {
    return state.layerBaseInfo[id]
  },
  setMediaInfo({ state }, mediaInfo) {
    console.log('mediaInfo', mediaInfo)
    state.mediaInfo = mediaInfo
  }
}

const storeOptions: StoreOptions<RootStateType> = {
  state: initStateFunc,
  getters,
  mutations,
  actions
}

const rootStore = createStore(storeOptions)

export default rootStore

export const storeKey: InjectionKey<Store<RootStateType>> = Symbol('')

type AllStateStoreTypes = RootStateType & {
  // moduleName: moduleType
}

export function useMyStore<T = AllStateStoreTypes>() {
  return useStore<T>(storeKey)
}
